﻿using System;
using System.Globalization;
using System.Threading;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.Xml;
using System.Reflection;
using Services;
using Utilities.Menu.UIElements;
using BowMaster.Resources;
using Services.Menu;
using Utilities;
using BowMaster.SceneElements;
using BowMaster.Menu;

namespace BowMaster.Levels
{
    
    public abstract class ALevel : CameraConsumer
    {
        static float MAX_POWER = 500;
        protected InputManager input_manager;
        protected SpriteBatch spriteBatch;
        protected StateManager StateManager;
        public int shoots = 0;
        protected SpriteFont arialHuge, arial18, arial14, arial10, arial16, arial12;
        MyButton menu, cheat, help;
        MyButton title, level_index;
        protected MyButton wind_level_b;
        public String Name;
        protected float press_wait;
        protected readonly float PRESS_INTERVAL = 0.5f;
        protected Random rnd;
        protected int index;
        protected Texture2D emptyTexture, whiteTexture, whiteBox, greyTexture;
        protected Texture2D background, /*obstacle, bowman, bow,*/ arrow, firingAreaTexture;
        protected Texture2D tree;
        public bool level_ended;
        public Color textColor;
        public Texture2D bgLevel;
        //public float bow_rotation;
        public Vector2 initial_drag_pos, final_drag_pos;
        public Arrow activeArrow;
        protected ArrayList<Arrow> disabledArrows;
        protected ArrayList<StaticObstacle> obstacles;
        public float current_zoom;
        static float MIN_ZOOM = 3;
        static float MAX_ZOOM = 0.5f;
        public float wind_level;
        public int level_width;
        public int level_height;
        public int level_x;
        public int level_y;
        protected bool updatePreview;
        private Texture2D levelMapTexture;
        private Rectangle levelMapRect;
        MyButton prevValuesText, actualValuesText;
        MyButton prevAngle_b, angle_b, prevPower_b, power_b;
        MyButton shoots_b;
        MyButton getBack_b;
        public BowMan player;
        protected Texture2D obstacleTexture, worriedTexture;
        Texture2D drag_t, pinch_t, double_tap_t;
        Rectangle rect1, rect2, rect3;
        MyButton text1, text2, text3;
        public bool showHelp;
        Rectangle helpRectangle;
        MyButton tapEveryWhere;
        public ALevel(Game game, int index, String name)
            : base(game)
        {
            Game.Services.RemoveService(typeof(InputManager));
            Game.Services.RemoveService(typeof(IInputManager));
            input_manager = new InputManager(Game);
            this.Name = name;
            this.index = index;
        }
        public ALevel(Game game, GraphicsDeviceManager graphics)
            : this(game, 0, "")
        { }

        public override void Initialize()
        {
          
            spriteBatch = Game.Services.GetService(typeof(SpriteBatch)) as SpriteBatch;
            StateManager = Game.Services.GetService(typeof(AStateManager)) as StateManager;

            Game.Components.Add(new CameraProvider(Game, CameraProvider.FIELDOFVIEW.PROSPECTIVE));

            input_manager.OnTap += on_tap;
            input_manager.OnDrag += on_drag;
            input_manager.OnVerticalDrag += on_drag;
            input_manager.OnHorizontalDrag += on_drag;
            input_manager.OnDragCompleted += on_drag_completed;
            input_manager.OnDoubleTap += on_double_tap;
            input_manager.OnPinch += on_pinch;

          
            base.Initialize();
        }
        protected override void Dispose(bool disposing)
        {
            Game.Services.RemoveService(typeof(IInputManager));
            base.Dispose(disposing);
        }


        protected override void LoadContent()
        {
            arialHuge = Game.Content.Load<SpriteFont>("Fonts/ArialHuge");
            arial18 = Game.Content.Load<SpriteFont>("Fonts/Arial18Ptx");
            arial16 = Game.Content.Load<SpriteFont>("Fonts/Arial16Ptx");
            arial14 = Game.Content.Load<SpriteFont>("Fonts/Arial14Ptx");
            arial10 = Game.Content.Load<SpriteFont>("Fonts/Arial10Ptx");
            arial12 = Game.Content.Load<SpriteFont>("Fonts/Arial12Ptx");
            emptyTexture = Game.Content.Load<Texture2D>("Textures/emptyPixel");
            whiteTexture = Game.Content.Load<Texture2D>("Textures/whitePixel");
            greyTexture = Game.Content.Load<Texture2D>("Textures/greyPixel");
            var bow = Game.Content.Load<Texture2D>("Textures/bow_p");
            var bowman = Game.Content.Load<Texture2D>("Textures/bowman_p");
            arrow = Game.Content.Load<Texture2D>("Textures/arrow");
            whiteBox = Game.Content.Load<Texture2D>("Textures/bar_box");
            tree = Game.Content.Load<Texture2D>("Textures/CypressTree");

            bgLevel = Game.Content.Load<Texture2D>("Textures/ground");
            obstacleTexture = Game.Content.Load<Texture2D>("Textures/wall");
            worriedTexture = Game.Content.Load<Texture2D>("Textures/worried");
            firingAreaTexture = Game.Content.Load<Texture2D>("Textures/firingArea");

            pinch_t = Game.Content.Load<Texture2D>("Textures/pinch");
            drag_t = Game.Content.Load<Texture2D>("Textures/drag");
            double_tap_t = Game.Content.Load<Texture2D>("Textures/double_tap");

            textColor = new Color(8, 141, 217);
            StateManager = Game.Services.GetService(typeof(AStateManager)) as StateManager;

            rnd = new Random();

            menu = new MyButton(new Rectangle(bar.X + 25,420 , 150, 50), Strings.ALevel_MainMenu, Color.White, arial14, TextPos.Center, whiteBox, Color.White);

            title = new MyButton(new Rectangle(bar.X, 20, 800 - bar.X, 50), Name, textColor, arial16);

            level_index = new MyButton(new Rectangle(bar.X, 0, 800 - bar.X, 40), "Level " + (index + 1), textColor, arial12);


            initial_drag_pos = Vector2.Zero;
            final_drag_pos = Vector2.Zero;
            


            disabledArrows = new ArrayList<Arrow>();
            obstacles = new ArrayList<StaticObstacle>();
            level_x = 0;
            level_y = level_height;
            land_y = level_height - 10;

            firingRectangle = new Rectangle(0, level_height-200, 300, 200);
            activeArrow = null;
            followArrow = false;
            firing = false;
            pinching = false;
            prevPiching = false; 
            levelMapTexture = null;
            //sceneBgRect = new Rectangle(0, 0, level_width, level_height);
            bgRect = new Rectangle(0, 0, level_width, level_height);
            //visibleRect = new Rectangle(level_x, level_y-480, bar.X, 480);
            visibleRect = new Rectangle(0, 0, bar.X, 480);
            press_wait = 0;
            level_ended = false;
            player = new BowMan(bowman, bow, 130, level_height - 120, 100);
            firstMove = true;
            preview_view = Matrix.CreateLookAt(
                    new Vector3(level_width / 2, level_height / 2, -(float)((level_height / 2) / Math.Sin(MathHelper.PiOver4) * Math.Cos(MathHelper.PiOver4))) + Vector3.Backward * current_zoom,
                    new Vector3(level_width / 2, level_height / 2, 0), Vector3.Down);
            updatePreview = false;
            var y = 180;
            prevValuesText = new MyButton(new Rectangle(bar.X, y, bar.Width, 50), Strings.ALevel_PrevValues, textColor, arial12, TextPos.Center);
            y += 25;
            prevAngle_b = new MyButton(new Rectangle(bar.X, y, bar.Width / 2, 50), Strings.ALevel_BowAngle + " 0 °", textColor, arial12, TextPos.Center);
            prevPower_b = new MyButton(new Rectangle(bar.X + bar.Width / 2, y, bar.Width / 2, 50), Strings.ALevel_Power + " 0 %", textColor, arial12, TextPos.Center);
            y += 25;
            actualValuesText = new MyButton(new Rectangle(bar.X, y, bar.Width, 50), Strings.ALevel_Values, textColor, arial12, TextPos.Center);
            y += 25;
            angle_b = new MyButton(new Rectangle(bar.X, y, bar.Width / 2, 50), Strings.ALevel_BowAngle + " 0 °", textColor, arial12, TextPos.Center);
            power_b = new MyButton(new Rectangle(bar.X + bar.Width / 2, y, bar.Width / 2, 50), Strings.ALevel_Power + " 0 %", textColor, arial12, TextPos.Center);
            
            wind_level = (float)Math.Round((rnd.NextDouble() / 2) - 0.5f, 1);
            wind_level_b = new MyButton(new Rectangle(bar.X, 100, 800 - bar.X, 50), Strings.ALevel_Wind + wind_level, textColor, arial14);
            y += 50;
            shoots_b = new MyButton(new Rectangle(bar.X, y, 800 - bar.X, 50), Strings.ALevel_Shoots + " " + shoots, textColor, arial14, TextPos.Center);

            getBack_b = new MyButton(new Rectangle(bar.X - 80, 200, 80, 80), Game.Content.Load<Texture2D>("Textures/back"), Color.White);

            showHelp = false;
            helpRectangle = new Rectangle(20, 20, bar.X - 40, 440);
            help = new MyButton(new Rectangle(menu.rectangle.X, 350, menu.rectangle.Width, menu.rectangle.Height),
                Strings.Help, Color.White, menu.font, TextPos.Center, whiteBox, Color.White);

            rect1 = new Rectangle(helpRectangle.X + 30, 60, 100, 100);
            rect2 = new Rectangle(helpRectangle.X + 30, 190, 100, 100);
            rect3 = new Rectangle(helpRectangle.X + 30, 320, 100, 100);

            text1 = new MyButton(new Rectangle(rect1.X+rect1.Width + 40, 60, 200, 100),
            "", Color.White, arial14, TextPos.Left);
            text2 = new MyButton(new Rectangle(rect2.X + rect2.Width + 40, 190, 200, 100), "", Color.White, arial14, TextPos.Left);
            text3 = new MyButton(new Rectangle(rect3.X + rect3.Width + 40, 320, 200, 100), Strings.DoubleTap + "\n\n" + Strings.DoubleTap_1,
                Color.White, arial14, TextPos.Left);
            tapEveryWhere = new MyButton(new Rectangle(helpRectangle.X, helpRectangle.Y + helpRectangle.Height - 40, helpRectangle.Width, 40),
                Strings.TapEverywhereToClose, Color.White, arial14);
            UpdateButtons();


#warning CHEAT for testing
            cheat = new MyButton(new Rectangle(170, 755, 140, 40), "Cheat", Color.White, arial14, TextPos.Center, whiteBox, Color.White);
            base.LoadContent();
            
        }
        
        protected Rectangle bar = new Rectangle(600, 0, 200, 480);
        Rectangle bgRect;
        Rectangle visibleRect;
        Color barColor = new Color(31, 31, 31);
        //Rectangle bowman_r;
        //Rectangle bow_r;
        Rectangle firingRectangle;
        //Rectangle sceneRectangle;
        //Vector2 bow_rot_origin = new Vector2(0, 73);
        int land_y;
        protected bool showGetBackButton;
        //Vector2 arrow_start;
        public virtual void Reset()
        {
            Game.Services.RemoveService(typeof(InputManager));
            Game.Components.Remove(input_manager);
            Game.Components.Add(input_manager);

            LoadContent();
        }
        public virtual void LevelWon()
        {
            StateManager.SelectNextLevel();
        }
        public virtual void LevelLost()
        {
            StateManager.SelectMainMenu();
        }
        bool followArrow;
        bool firing, pinching, prevPiching;
        bool firstMove;
        public override void Update(GameTime gameTime)
        {
            //shoots += (float)gameTime.ElapsedGameTime.TotalSeconds;
            var dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
            if (press_wait < PRESS_INTERVAL)
                press_wait += dt;

            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            {
                if (showHelp)
                    showHelp = false;
                else
                {
                    StateManager.SelectMainMenu();
                    return;
                }
            }
            if (!showHelp)
            {
                if (firstMove)
                {
                    firstMove = MoveScene(0, -5);
                    //firstMove = false;
                }




                if (showGetBackButton && level_x == 0 && level_y == 480)
                    showGetBackButton = false;
                //else if (!showGetBackButton && (level_x != 0 || level_y != 480))
                //    showGetBackButton = true;
                if (activeArrow != null)
                {
                    var newPos = activeArrow.position + activeArrow.velocity * dt;
                    //activeArrow.position += activeArrow.velocity * dt;
                    activeArrow.velocity.Y += 1.6f;
                    activeArrow.velocity.X += wind_level;
                    if (followArrow)
                        MoveScene((int)(activeArrow.position.X - newPos.X), (int)(activeArrow.position.Y - newPos.Y));

                    activeArrow.position = newPos;
                    activeArrow.point = (Vector2.Normalize(activeArrow.velocity) * arrow.Bounds.Width * 1.5f) + activeArrow.position;
                    //activeArrow.point = activeArrow.position + activeArrow.velocity;

                    for (int i = 0; i < obstacles.Count; i++)
                        if (obstacles[i].Hitted(activeArrow))
                        {
                            disabledArrows.Add(activeArrow);
                            activeArrow = null;
                            showGetBackButton = true;
                            if (obstacles[i].life <= 0)
                                LevelLost();
                            break;
                        }

                    if (activeArrow != null && activeArrow.point.Y > land_y)
                    {
                        disabledArrows.Add(activeArrow);
                        //activeArrow.Disable();
                        activeArrow = null;
                        showGetBackButton = true;
                    }
                    if (activeArrow != null && (activeArrow.point.X > level_width || activeArrow.point.X < 0))
                    {
                        activeArrow = null;
                        MoveScene(level_x, -level_y);
                    }
                }
                if (prevPiching && !pinching)
                    FireArrow();

                prevPiching = pinching;

                if (activeArrow == null && shoots == 0)
                    StateManager.SelectMainMenu();
            }
            base.Update(gameTime);
        }
        public virtual void DrawArrows()
        {
            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
            if (activeArrow != null)
                activeArrow.Draw(spriteBatch, view, projection);
            
            for (int i = 0; i < disabledArrows.Count; i++)
                disabledArrows[i].Draw(spriteBatch, view, projection);
            
        }
        float a = 300;
        public virtual void DrawLevelElements(){

            GraphicsDevice.DepthStencilState = DepthStencilState.Default;

            spriteBatch.DrawTexture(bgLevel, Color.White, 
                Matrix.CreateRotationX(-MathHelper.PiOver2) *                 
                Matrix.CreateScale(level_width*3, 0, 200) *
                Matrix.CreateTranslation(-level_width, level_height, 200)
                , view, projection);
            a += 1f;
            
            //spriteBatch.DrawTexture(bgLevel, bgRect, Color.White, view, projection);
            
            spriteBatch.DrawTexture(tree, new Rectangle(200, level_height-200, 150, 200), 120, Color.White, view, projection);
            spriteBatch.DrawTexture(tree, new Rectangle(330, level_height - 200, 180, 200), 160, Color.White, view, projection);

            player.Draw(spriteBatch, view, projection);
            //spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);
            for (int i = 0; i < obstacles.Count; i++)
                obstacles[i].Draw(spriteBatch, view, projection);
            //spriteBatch.End();
        }

        Matrix preview_view;
        RenderTarget2D rt;
        protected void BuildMapPreview()
        {
            var prev_view = view;
            view = preview_view;
            if(rt==null)
                rt = new RenderTarget2D(GraphicsDevice, level_width, level_height, false, SurfaceFormat.Color, DepthFormat.Depth24Stencil8);
            
            GraphicsDevice.SetRenderTarget(rt);
            GraphicsDevice.Clear(Color.White);
            DrawLevelElements();
            
            GraphicsDevice.SetRenderTarget(null);
            levelMapTexture = (Texture2D)rt;

            levelMapRect = new Rectangle(bar.X/2 - levelMapTexture.Width / 16, 16, levelMapTexture.Width / 8, levelMapTexture.Height / 8);


            view = prev_view;
        }
        long ticks = 1;
        public override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Azure);

            if (levelMapTexture == null && view!=new Matrix(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0))
            {
                BuildMapPreview();
            }
            
            if (updatePreview && ticks++ % 30 == 0)
            {
                BuildMapPreview();
                ticks = 0;
            }
            GraphicsDevice.Clear(Color.Azure);
            DrawLevelElements();
            DrawArrows();
            spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);
            if (StateManager.OptionsState.inputType == Menu.InputType.SingleDrag)
                spriteBatch.Draw(firingAreaTexture, firingRectangle, Color.Red);

            spriteBatch.Draw(whiteTexture, bar, barColor);
            menu.Draw(spriteBatch);
            //cheat.Draw(spriteBatch);
            help.Draw(spriteBatch);
            title.Draw(spriteBatch);
            if(index>=0)
                level_index.Draw(spriteBatch);
            wind_level_b.Draw(spriteBatch);
            prevValuesText.Draw(spriteBatch);
            actualValuesText.Draw(spriteBatch);
            prevAngle_b.Draw(spriteBatch);
            prevPower_b.Draw(spriteBatch);
            var angle = (int)((360-MathHelper.ToDegrees(player.bow_rotation))) % 360;
            angle_b.text = Strings.ALevel_BowAngle + " " + angle + " °";
            var power = 0;
            if (firing || pinching)
                power = (int)Vector2.Distance(initial_drag_pos, final_drag_pos)*2;
            power_b.text = Strings.ALevel_Power + " " + (int)((Math.Min(power,MAX_POWER) / MAX_POWER)*100) + " % ";
            shoots_b.text = Strings.ALevel_Shoots + " " + shoots;
            shoots_b.Draw(spriteBatch);
            angle_b.Draw(spriteBatch);
            power_b.Draw(spriteBatch);
            if (showGetBackButton)
                getBack_b.Draw(spriteBatch);
            if (levelMapTexture != null)
            {
                spriteBatch.Draw(levelMapTexture, levelMapRect, Color.White);
                spriteBatch.Draw(whiteTexture, levelMapRect, Color.Black * 0.2f);
                var visible = new Rectangle(
                    levelMapRect.X + visibleRect.X * levelMapRect.Width / level_width,
                    levelMapRect.Y + visibleRect.Y * levelMapRect.Height / level_height,
                    visibleRect.Width * levelMapRect.Width / level_width,
                    visibleRect.Height * levelMapRect.Height / level_height);

                spriteBatch.Draw(levelMapTexture, visible, visibleRect, Color.White);
            }

            spriteBatch.Draw(firingAreaTexture, levelMapRect, Color.Black);

            if (showHelp)
            {
                spriteBatch.Draw(whiteTexture, helpRectangle, Color.Black * 0.7f);
                spriteBatch.Draw(drag_t, rect1, Color.White);
                spriteBatch.Draw(pinch_t, rect2, Color.White);
                spriteBatch.Draw(double_tap_t, rect3, Color.White);

                text1.Draw(spriteBatch);
                text2.Draw(spriteBatch);
                text3.Draw(spriteBatch);
                tapEveryWhere.Draw(spriteBatch);
            }

            spriteBatch.End();
            base.Draw(gameTime);
        }
        Point tp = new Point();
        protected void on_tap(Vector2 tap)
        {
            if (press_wait < PRESS_INTERVAL || level_ended) return;
            press_wait = 0;
            tp.X = (int)tap.X;
            tp.Y = (int)tap.Y;
            if (showHelp)
                showHelp = false;
            else
            {
                if (menu.tapped_on(tp))
                {
                    exit_level();
                }
                else if (showGetBackButton && getBack_b.tapped_on(tp))
                {
                    showGetBackButton = false;
                    MoveScene(level_x, -level_y);
                }
                else if (!showHelp && help.tapped_on(tp))
                {
                    showHelp = true;
                }
                //else if (cheat.tapped_on(tp))
                //    StateManager.SelectNextLevel();
            }
            
        }
        
        bool zoomed_in = false;
        void on_drag(Vector2 drag_pos)
        {
            if (showHelp)
                return;

            followArrow = false;
            switch (StateManager.OptionsState.inputType)
            {
                case Menu.InputType.SingleDrag:
                    {
                        if (firing || StaticUtilities.RectContainsVect(firingRectangle,drag_pos))
                        {
                            if (activeArrow != null)
                                return;
                            firing = true;
                            if (initial_drag_pos != Vector2.Zero)
                            {

                                final_drag_pos = drag_pos;
                                SetBowRotation();
                            }
                            else

                                initial_drag_pos = drag_pos;
                        }
                        else
                        {
                            firing = false;
                            if (initial_drag_pos != Vector2.Zero)
                            {
                                var deltax = (int)(drag_pos.X - initial_drag_pos.X);
                                var deltay = (int)(drag_pos.Y - initial_drag_pos.Y);

                                MoveScene(deltax / 2, deltay / 2);
                            }
                            initial_drag_pos = drag_pos;
                        }
                    }
                    break;
                case Menu.InputType.PinchToFire:
                    {
                        firing = false;
                        if (initial_drag_pos != Vector2.Zero)
                        {
                            var deltax = (int)(drag_pos.X - initial_drag_pos.X);
                            var deltay = (int)(drag_pos.Y - initial_drag_pos.Y);

                            MoveScene(deltax / 2, deltay / 2);
                        }
                        initial_drag_pos = drag_pos;
                    }
                    break;
            }
        }
        private void SetBowRotation()
        {
            var a = (float)Math.Acos(Vector2.Dot(Vector2.UnitX, Vector2.Normalize(final_drag_pos - initial_drag_pos)));
            a += (float)Math.PI;

            if (final_drag_pos.Y < initial_drag_pos.Y)
                a = 0;
            else if (a < 5.00)
                a = 5.0f;
            if (float.IsNaN(a))
                a = 0;
            player.bow_rotation = a;
        }
        void on_drag_completed()
        {
            if (showHelp)
                return;
            if (firing && StateManager.OptionsState.inputType==Menu.InputType.SingleDrag)
            {
                if (activeArrow != null) return;
                FireArrow();
            }
            else
                initial_drag_pos = Vector2.Zero;
        }
        
        void on_double_tap(Vector2 tap_position)
        {
            if (zoomed_in)
                current_zoom = MIN_ZOOM;
            else
                current_zoom = MAX_ZOOM;
            zoomed_in = !zoomed_in;
            provider.view *= Matrix.CreateTranslation(new Vector3(0, 0, current_zoom));
        }
        void on_pinch(Vector2 position1, Vector2 position2, Vector2 delta1, Vector2 delta2)
        {
            if (showHelp)
                return;
            if (StateManager.OptionsState.inputType == Menu.InputType.PinchToFire)
            {
                if (activeArrow != null) return;
                if (delta1==Vector2.Zero)
                {
                    pinching = false;
                }
                else
                {
                    pinching = true;
                    initial_drag_pos = position2;
                    final_drag_pos = position1;
                    SetBowRotation();
                }
            }
            else
            {
                //Console.WriteLine(position1 + " - " + position2 + " " + delta1 + " - " + delta2);

                var temp = current_zoom - (Vector2.Distance(position1, position2) - Vector2.Distance(position1 - delta1, position2 - delta2)) * .01f;

                current_zoom = Math.Max(MAX_ZOOM, Math.Min(MIN_ZOOM, temp));
                provider.view *= Matrix.CreateTranslation(new Vector3(0, 0, temp));
            }
            
        }
        private void FireArrow()
        {
            if (activeArrow != null) return;
            firing = false;
            followArrow = true;
            pinching = prevPiching = false;
            if (final_drag_pos.X > initial_drag_pos.X)// || final_drag_pos.Y < initial_drag_pos.Y)
            {
                player.bow_rotation = 0;
                return;
            }

            if (float.IsNaN(player.bow_rotation))
                return;
            var d = Vector2.Distance(initial_drag_pos, final_drag_pos) * 2.5f;
            if (d < 60)
                return;
            d = Math.Min(d, MAX_POWER);
            var velocity = Vector2.UnitX * (float)Math.Cos(player.bow_rotation) + Vector2.UnitY * (float)Math.Sin(player.bow_rotation);
            velocity *= d;
            activeArrow = new Arrow(arrow, player.arrow_start, velocity);

            initial_drag_pos = Vector2.Zero;
            final_drag_pos = Vector2.Zero;

            prevAngle_b.text = angle_b.text;
            prevPower_b.text = power_b.text;
            shoots--;
        }
        private bool MoveScene(int deltax, int deltay)
        {
            var o_deltax = deltax;
            var o_deltay = deltay;
            if (level_width - level_x + deltax < bar.X)
                deltax = bar.X - (level_width - level_x);  //PERFETTO!!!!!

            if (deltax>0 && level_x - deltax < 0)  //PERFETTO
                deltax = level_x;


            if (level_y + deltay < 480)
                deltay = 480 - level_y;  //PERFETTO

            if (deltay > 0 && level_y + deltay > level_height)
                deltay = level_height - level_y;   //PERFETTO




            visibleRect.X -= deltax;
            visibleRect.Y -= deltay;


            //bgRect.X += deltax;
            //bgRect.Y += deltay;

            level_x -= deltax;
            level_y += deltay;
            firingRectangle.X += deltax;
            firingRectangle.Y += deltay;

            //bow_r.X += deltax;
            //bow_r.Y += deltay;
            //bow_rot_origin.X += deltax;
            //bow_rot_origin.Y += deltay;
            //arrow_start.X += deltax;
            //arrow_start.Y += deltay;
            //bowman_r.X += deltax;
            //bowman_r.Y += deltay;


            provider.view *= Matrix.CreateTranslation(new Vector3(deltax, -deltay, 0));
            //if (activeArrow != null)
            //{
            //    //activeArrow.position.X += deltax;
            //    //activeArrow.position.Y += deltay;
            //}
            return deltax==o_deltax && deltay == o_deltay;
        }

        public Vector2 centerString(Rectangle rectangle, string text, SpriteFont spriteFont)
        {
            Vector2 destinazione = new Vector2();
            if (text == null || text == "") return new Vector2(rectangle.Center.X, rectangle.Center.Y);
            Vector2 dimStringa = spriteFont.MeasureString(text);

            destinazione.X = rectangle.X + rectangle.Width / 2 - dimStringa.X / 2;
            destinazione.Y = rectangle.Y + rectangle.Height / 2 - dimStringa.Y / 2;

            return destinazione;
        }
        public Vector2 centerString(Rectangle rectangle, string text, SpriteFont spriteFont, float scale)
        {
            Vector2 destinazione = new Vector2();
            if (text == null || text == "") return new Vector2(rectangle.Center.X, rectangle.Center.Y);
            Vector2 dimStringa = spriteFont.MeasureString(text) * scale;

            destinazione.X = rectangle.X + rectangle.Width / 2 - dimStringa.X / 2;
            destinazione.Y = rectangle.Y + rectangle.Height / 2 - dimStringa.Y / 2;

            return destinazione;
        }
        public virtual void exit_level(){
            StateManager.SelectMainMenu();
        }
        private void UpdateButtons()
        {
            switch (StateManager.OptionsState.inputType)
            {
                case InputType.PinchToFire:
                    text1.text = Strings.Drag + "\n\n" + Strings.Drag2_1;
                    text2.text = Strings.Pinch + "\n\n" + Strings.Pinch2_1;
                    break;
                case InputType.SingleDrag:
                    text1.text = Strings.Drag + "\n\n" + Strings.Drag1_1 + "\n" + Strings.Drag1_2 + "\n" + Strings.Drag1_3 + "\n" + Strings.Drag1_4;
                    text2.text = Strings.Pinch + "\n\n" + Strings.Pinch1;
                    break;
            }
            text1.UpdateTextPos();
            text2.UpdateTextPos();
        }
    }


}
